#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// 温度
#include <OneWire.h>
#include <DallasTemperature.h>

#define led 2
#define theemometer_gp 14

// wifi info
const char *SSID = "优美屋205";
const char *PASSWORD = "18111549";

// mqtt info
const char *MQTT_SERVER = "broker-cn.emqx.io";
const int MQTT_PROT = 1883;

// mqtt 主题
const char *MQTT_TOPIC_ONLINE = "xapi/home/online";
const char *MQTT_TOPIC_UPDATE = "xapi/home/update";
const char *CLIENT_ID = "esp8266-457065e5-f063-474e-2saf-cacf5cb52af5";

float wb_num = 0.00;
char *wb_num_str = "";

WiFiClient espClient;
PubSubClient client(espClient);

OneWire oneWire(theemometer_gp);  
DallasTemperature sensors(&oneWire);

void init_wifi();
void mqtt_reconnect();
void mqtt_msg_callback(char *topic, byte *payload, unsigned int length);
void wb_update(); // 温度发送

void setup() {
  Serial.begin(115200);
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  init_wifi();
  client.setServer(MQTT_SERVER, MQTT_PROT);
  client.setCallback(mqtt_msg_callback);
  sensors.begin();  // 温度计开始
}

void loop() {
  if(!client.connected()){
    mqtt_reconnect();
  }
  client.loop();
  wb_update();
}

void init_wifi(){
  Serial.println("连接中...");
  Serial.println(SSID);

  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
}

void mqtt_reconnect(){
  while (!client.connected())
  {
    Serial.print("正在尝试MQTT连接");

    if(client.connect(CLIENT_ID)){
      Serial.println("已连接");
      client.publish(MQTT_TOPIC_ONLINE, "online"); // 发布
    }else{
      Serial.print("错误, rc");
      Serial.print(client.state());
      Serial.println("等待 5s");
      delay(5000);
    }
  }
}

void mqtt_msg_callback(char *topic, byte *payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic); // 打印主题信息
  Serial.print("] ");
}

void wb_update(){
  if(client.connected()){
    wb_num = sensors.getTempCByIndex(0);
    dtostrf(wb_num, 2, 2, wb_num_str); // 浮点转字符串

    sensors.requestTemperatures();
    Serial.print("Temperature: ");
    Serial.print(wb_num); // 以摄氏度为单位打印温度
    Serial.print("c  |  ");

    Serial.print((wb_num * 9.0) / 5.0 + 32.0); // 以华氏度打印温度
    Serial.println("F");
    digitalWrite(led, HIGH);
    delay(1000);
    client.publish(MQTT_TOPIC_UPDATE, wb_num_str);
    digitalWrite(led, LOW);
    delay(500);
  }
}
